%% copy riak-0.14.2 source to learn dynamo implementation and erlang
%% author: lichuang
%% copy source from riak_core_node_watcher_events.erl
-module(edynamo_node_watcher_events).
-behaviour(gen_event).
%% API
-export([start_link/0,
         add_handler/2,
         add_sup_handler/2,
         add_callback/1,
         add_sup_callback/1,
         service_update/1]).
%% gen_event callbacks
-export([init/1, handle_event/2, handle_call/2,
         handle_info/2, terminate/2, code_change/3]).

-record(state, { callback }).
%% ===================================================================
%% API functions
%% ===================================================================
start_link() ->
  gen_event:start_link({local, ?MODULE}).

add_handler(Handler, Args) ->
  gen_event:add_handler(?MODULE, Handler, Args).

add_sup_handler(Handler, Args) ->
  gen_event:add_sup_handler(?MODULE, Handler, Args).

add_callback(Fn) when is_function(Fn) ->
    gen_event:add_handler(?MODULE, {?MODULE, make_ref()}, [Fn]).

add_sup_callback(Fn) when is_function(Fn) ->
    gen_event:add_sup_handler(?MODULE, {?MODULE, make_ref()}, [Fn]).

service_update(Services) ->
  gen_event:notify(?MODULE, {service_update, Services}).

%% ===================================================================
%% gen_event callbacks
%% ===================================================================
init([Fn]) ->
  %% Get the initial list of available services
  Fn(edynamo_node_watcher:services()),
  {ok, #state {callback = Fn}}.

handle_event({service_update, Services}, State) ->
    (State#state.callback)(Services),
    {ok, State}.

handle_call(_Request, State) ->
    {ok, ok, State}.

handle_info(_Info, State) ->
    {ok, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.
